/***************************Copyright QYKJ   2015-06-18*************************
文	件：	Thread.c
说	明：	线程实现函数
编	译：	Keil uVision4 V4.54.0.0
版	本：	v1.1
编	写：	Unarty
修　改：	2014.06.18 创建 
			2014.08.30 //修改单次延时注册线程，延时零毫秒不能执行问题
			2015.05.02 修改线程查找方式，加快查找速度。修改线程时间变量处理方式，增加线程可移植性 
			2016.08.05 unarty 修改任务结构体，增加任务查找函数，与随机值获取函数
			2016.08.10 unarty 增加任务延时响应注册。
			2016.08.16 Unarty 修改优化任务注册逻辑（减少已注册任务重复查找）;任务换醒立即生效; 随机产生方式（参考C语言）; 增加线程负载统计获取接口
            2021.08.03 Unarty 进一步简化线程任务管理方法，减少本身管理产生的系统资源消耗。
                    1、任务同期心跳计数简化，将任务表中的周期计算置换到，任务执行环节计算。减少中断任务中资源占用，减少系统对其它中断的影响。
                    2、任务注销时不再对任务表单中后面的任务进行移动覆盖等内存操作，将其换成内存有效标记，减少任务注销时资源消耗。
                    3、移除挂起/唤醒的管理接口。（任务的注册/注销占用资源很小，对任务挂起的需求，可通过注销与重新注册的方式实现）
            2021.08.04 Unarty 将任务Tick计数器放置到由外部直接增减，如此即可直接取值相关外设计数器值。减少因线程心跳计数而产生的中断消耗，
            2021.08.25 Unarty  Tick计数器重新归类到管理函数中，保存其变量的整体性
*******************************************************************************/
#include "Thread.h"

#define  THREAD_USER_FLAG       (0x5A)


static void _onceDelay(Thread_t *th);
static void _many(Thread_t *th);
static void _forever(Thread_t *th);
static void _delete(Thread_t *pTh);

typedef void (*void_fun_Thread_t)(Thread_t *th);
const void_fun_Thread_t _runTab[] ={
    _onceDelay,
    _many,
    _forever,  
 };

typedef struct {
    u32_t   	tick;   
    Thread_t    *end;
    Thread_t    tab[THREAD_NUM];
}ThreadManage_t;

static ThreadManage_t _thread = {0};


/*******************************************************************************
功能说明:    Thread_login 线程注册 
    参数:   con: 线程类型    
                ONCE_DELAY:延时固定时间后执行目标注册函数，执行完后任务自动注销
                MANY：按注册任务的次数，调用注册函数次数达到目标值后自动注销任务
                FOREVER： 不主动对任务进行注销操作，按注册需求周期调用。
            cnt: 任务已执行次数初始值。当线程类型为MANY,即为目标任务执行次数。
            frep: 任务调用频率，任务频率的基数为系统Tickr的频率，       
            fun:   函数入口地址
  返回值:   注册任务参数值，null: 注册失败。
*******************************************************************************/
Thread_t * Thread_login(ThreadCon_e con, u16_t cnt, u32_t frep, void_fun_void fun) {
    Thread_t  *p, *pTh = null;
    /*找空缺位置*/
    for (p = _thread.tab; p < _thread.end || (pTh == null && p < &_thread.tab[THREAD_NUM]); p++) {
        if (p->flag == THREAD_USER_FLAG) {
            if (p->exeFun == fun) {
                if (pTh != null) { //释放最靠前位置
                    pTh->flag = 0;
                }
                pTh = p;
                break;
            }
        } else if (pTh == null) { //最靠前的空缺位置优先
            p->flag = THREAD_USER_FLAG;
            p->exeFun = fun;
            pTh = p;
        } 
    }
    
    if (pTh != null ) {
        pTh->conf = con;
        pTh->cnt = cnt;
        pTh->tick = _thread.tick;
        pTh->frep = frep;
       
        if (pTh > _thread.end) {
            _thread.end = pTh;
        }
    }

    return pTh;
}

/*******************************************************************************
功能说明:    Thread_logout 线程注销
    参数:   fun:   函数入口地址 
  返回值:   无
*******************************************************************************/
void Thread_logout(void_fun_void fun) {
    Thread_t *th = Thread_find(fun);
    if (th != null) {
        _delete(th);
    }
}

/*******************************************************************************
功能说明:    Thread_tick 线程心跳， 此函数的调用频率即为任务管理器的心跳周期。
    参数:   无
  返回值:   无
*******************************************************************************/
void Thread_tick(void) {

    _thread.tick++;
}

/*******************************************************************************
功能说明:   线程查找
    参数:   fun:   函数入口地址 
  返回值:   null：未找到。非NNULL：线程的所有参数值
*******************************************************************************/
Thread_t *Thread_find(void_fun_void fun) {
    Thread_t *pTh;

    for (pTh =_thread.tab; pTh <= _thread.end; pTh++) {
        if (pTh->flag == THREAD_USER_FLAG && (pTh->exeFun == fun)) {
            return pTh;
        }
    }
   
    return null;
}

/*******************************************************************************
功能说明:  线程处理， 函数需在任务
    参数:  无
  返回值:  当前任务表中有效任务总数
*******************************************************************************/
u32_t Thread_run(void) {
    u32_t cal, i;
    Thread_t *pTh;

    for (pTh =_thread.tab, i = 0; pTh <= _thread.end; pTh++) {
        if (pTh->flag == THREAD_USER_FLAG) {
            cal = _thread.tick;
            cal = cal >= pTh->tick ? cal - pTh->tick : 0xFFFFFFFF - pTh->tick + cal;
            
            if (cal >= pTh->frep) {	//
                pTh->tick = _thread.tick;
                _runTab[pTh->conf](pTh);
            } 
            i++;
        }
    } 

    return  i;
}
/*******************************************************************************
功能说明:  随机数
    参数:  无
  返回值:  依据任务特性而产生的随机数
*******************************************************************************/
u32_t Thread_rand(void){
    u32_t random;

    random = _thread.tick;
    random <<= 11;
    random += _thread.tick<<6;
    random += _thread.tick;
      
    return random;
}
/*******************************************************************************
功能说明:  线程心跳总数
    参数:  无
  返回值:  系统执行到现在的累计值
*******************************************************************************/
u32_t Thread_tickCount(void){
    return _thread.tick;
}
/*******************************************************************************
功能说明:  随机数
    参数:  无
  返回值:  返回一个依据任务特性而产生和随机数
*******************************************************************************/
static void _delete(Thread_t *pTh) {

    pTh->flag = 0;

    while (pTh->flag != THREAD_USER_FLAG && pTh >= _thread.tab &&  pTh == _thread.end ) {
        _thread.end--;
        pTh--;
    }
}
/*******************************************************************************
功能说明:  单次延时任务执行
    参数:  th: 注册任务参数
  返回值:  无
*******************************************************************************/
static void _onceDelay(Thread_t *th) {
    void_fun_void fun = th->exeFun;

    _delete(th);
    fun();
}
/*******************************************************************************
功能说明:  多次任务执行
    参数:  th: 注册任务参数
  返回值:  无
*******************************************************************************/
static void _many(Thread_t *th) {
    th->exeFun();
    if (!(--th->cnt)) {	
        _delete(th);
    }
}
/*******************************************************************************
功能说明:   常驻任务执行
    参数:  th: 注册任务参数
  返回值:  无
*******************************************************************************/
static void _forever(Thread_t *th) {
    th->cnt++;
    th->exeFun();
}

/*******************************Copyright QYKJ*********************************/
